home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Periodicals / develop / develop 9 code / Tracks / Tracks ƒ / dumptracks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-06  |  27.0 KB  |  1,286 lines  |  [TEXT/MPS ]

  1. #include "DumpTracks.h"
  2. #include <Stdio.h>
  3. #include <Files.h>
  4. #include <Folders.h>
  5.  
  6. #include <String.h>
  7. #include "Packages.h"
  8. #ifndef THINK_C
  9. #include <Strings.h>
  10. #include <Resources.h>
  11. #include <Memory.h>
  12. #include "Types.h"
  13. #include "Errors.h"
  14. #include "OSUtils.h"
  15. #include "StdLib.h"
  16. #include "ToolUtils.h"
  17. #endif
  18.  
  19. shex gReadBuff[1024];
  20. shex gReadBuffSize;
  21. Ptr fRecordBuffer;
  22. char printBuff[1000];
  23. char *fPrintBuffer;
  24. char gFileName[100];
  25. short    lastDiagID =-1;    
  26. short    gPrefsVRefNum;
  27. Boolean    gVerboseMode =1;
  28. SysEnvRec gEnvironment;
  29.  
  30. #ifndef THINK_C
  31. main(int argc, char **argv)
  32. #else
  33. main()
  34. #endif
  35. {
  36. snum result;
  37. short refNum;
  38. short    SysFolderRefNum;
  39. short PrefsResRefNum, infoFileRefNum=-1;
  40. Handle    driverName;
  41.         
  42.     fRecordBuffer = (Ptr) gReadBuff;
  43.     fPrintBuffer = printBuff;
  44.     gReadBuffSize = sizeof(gReadBuff);
  45.  
  46.     (void) SysEnvirons(1, &gEnvironment);
  47.     SysFolderRefNum = gEnvironment.sysVRefNum;        // Get the sys folder vref
  48.     
  49.     gPrefsVRefNum = GetFolderVol(kPreferencesFolderType);
  50.         
  51.     if (gPrefsVRefNum == 0) 
  52.     {
  53.         printf("Error finding preference folder\n");
  54.         gPrefsVRefNum = SysFolderRefNum;
  55.     }
  56.     
  57.     strcpy(gFileName,(char *)"\pTracks Prefs");
  58.     
  59. #ifndef THINK_C
  60.     ParseArgs(argc, argv);
  61. #endif
  62.  
  63.     PrefsResRefNum = OpenRFPerm(gFileName, gPrefsVRefNum, fsRdWrPerm);
  64.     result = ResError();
  65.     if (result != 0) 
  66.     {
  67.         printf("Abort: prefs file get Error #%d", result);
  68.         exit(3);
  69.     }
  70.  
  71.     result = FSOpen(gFileName, 0, &refNum);
  72.     if (result != noErr)
  73.         {
  74.             SetVol(nil, gPrefsVRefNum);
  75.             result = FSOpen(gFileName,0,&refNum);    
  76.         }
  77.  
  78.     if (result == noErr)
  79.         {        
  80.  
  81.         p2cstr(gFileName);
  82.         
  83.         driverName = GetResource('kDRp', 128);
  84.         if (driverName!=nil)
  85.         {
  86.             infoFileRefNum = OpenRFPerm(*driverName, SysFolderRefNum, fsRdWrPerm);
  87.             if (infoFileRefNum == -1) 
  88.                 infoFileRefNum = OpenRFPerm(*driverName, GetFolderVol(kExtensionFolderType), fsRdWrPerm);
  89.             if (infoFileRefNum == -1) 
  90.                 infoFileRefNum = OpenRFPerm(*driverName, GetFolderVol(kControlPanelFolderType), fsRdWrPerm);
  91.             if (infoFileRefNum == -1) 
  92.                 printf("Warning:  Couldnt load name list\n");
  93.             ReleaseResource(driverName);
  94.         } else printf("Pref File data not found");
  95.  
  96.         //if (gVerboseMode)    
  97.         //    printf("Dumping file %s   \n", gFileName);
  98.  
  99.         }
  100.  
  101.     TypeDumpSetUp(SysFolderRefNum);    // Set up template (format06) printing (reads in 'mxwt' resources)
  102.         
  103.     result = ReadFileRecords(refNum);
  104.     if (result == noErr || result == eofErr)
  105.         if (gVerboseMode)    printf("\n--- End of dump ---\n");
  106.     else
  107.         {
  108.         printf("--- Dump terminated, error = %d ---\n", result);
  109.         if (result == -43) printf("(File not found)\n");
  110.         }
  111.         
  112.     if (infoFileRefNum != -1) 
  113.         CloseResFile(infoFileRefNum);
  114.     TypeDumpCloseDown();
  115.     (void) FSClose(refNum);
  116.     CloseResFile(PrefsResRefNum);
  117.     exit(0);
  118. }
  119.  
  120. short GetFolderVol(OSType type)
  121. {
  122. WDPBRec        wdParamBlock;        /*param block to set up working directory*/
  123. short         result;
  124. short         prefVRef;
  125. long         prefDirID;
  126.  
  127.     if (gEnvironment.systemVersion <= 0x607)     // added 12/2
  128.         return gEnvironment.sysVRefNum;
  129.  
  130.     result=FindFolder(kOnSystemDisk, type, true, &prefVRef, &prefDirID);
  131.     if (result == 0)
  132.     {
  133.         wdParamBlock.ioCompletion = NULL;
  134.         wdParamBlock.ioNamePtr = NULL;
  135.         wdParamBlock.ioVRefNum = prefVRef;
  136.         wdParamBlock.ioWDDirID = prefDirID;
  137.         result=PBOpenWD(&wdParamBlock, false);
  138.         if (result == 0)
  139.             return wdParamBlock.ioVRefNum;
  140.     }
  141.     return 0;
  142. }
  143.  
  144.  
  145. void CopyEbcdicToAscii(unsigned char *ebcdic, unsigned char *toAscii,
  146.  unsigned short dataLength)
  147.     {
  148.  
  149.     unsigned char *asciiArray;
  150.     
  151.     // String pointer used to avoid data initialization...
  152.  
  153.     asciiArray = (unsigned char *)
  154.         "\000\001\002\003\234\011\206\177"
  155.         "\227\215\216\013\014\015\016\017"
  156.         "\020\021\022\023\235\205\010\207"
  157.         "\030\031\222\217\034\035\036\037"
  158.         "\200\201\202\203\204\012\027\033"
  159.         "\210\211\212\213\214\005\006\007"
  160.         "\220\221\026\223\224\225\226\004"
  161.         "\230\231\232\233\024\025\236\032"
  162.         "\040\240\241\242\243\244\245\246"
  163.         "\247\250\133\056\074\050\053\041"
  164.         "\046\251\252\253\254\255\256\257"
  165.         "\260\261\135\044\052\051\073\136"
  166.         "\055\057\262\263\264\265\266\267"
  167.         "\270\271\174\054\045\137\076\077"
  168.         "\272\273\274\275\276\277\300\301"
  169.         "\302\140\072\043\100\047\075\042"
  170.         "\303\141\142\143\144\145\146\147"
  171.         "\150\151\304\305\306\307\310\311"
  172.         "\312\152\153\154\155\156\157\160"
  173.         "\161\162\313\314\315\316\317\320"
  174.         "\321\176\163\164\165\166\167\170"
  175.         "\171\172\322\323\324\325\326\327"
  176.         "\330\331\332\333\334\335\336\337"
  177.         "\340\341\342\343\344\345\346\347"
  178.         "\173\101\102\103\104\105\106\107"
  179.         "\110\111\350\351\352\353\354\355"
  180.         "\175\112\113\114\115\116\117\120"
  181.         "\121\122\356\357\360\361\362\363"
  182.         "\134\237\123\124\125\126\127\130"
  183.         "\131\132\364\365\366\367\370\371"
  184.         "\060\061\062\063\064\065\066\067"
  185.         "\070\071\372\373\374\375\376\377";
  186.  
  187.     
  188.     while (dataLength > 0)
  189.         {
  190.         *toAscii++ = asciiArray[(*ebcdic++)];
  191.         dataLength--;
  192.         }
  193.     
  194.     return;
  195.     
  196.     }
  197.  
  198. CopyPStr(char *src, char *dst)
  199. {
  200. register char x,len;
  201.     len = *src;
  202.     
  203.     for (x=0;x<=len;x++)
  204.         *dst++ = *src++;
  205.  
  206. }
  207.  
  208. snum DecodeSym(char *stringBuffer, char *symbol, Boolean showTypeInfo, Ptr stackdataPtr)
  209.     {
  210.     char *funcNamePtr;
  211.     char *classNamePtr;
  212.     snum funcNameLength;
  213.     snum classNameLength;
  214.     char *typeInfoPtr;
  215.     char *p, *copy;
  216.     snum len;
  217.     snum i, j;
  218.     char *modUstr = "unsigned";
  219.     char modUstrlen = 8;
  220.     char *argPtr;
  221.     char *typeNamePtr;
  222.     char typeNameLen;
  223.     snum typesize;
  224.     char *argNamePtr[32];
  225.     snum argNameLen[32];
  226.     snum argCount;
  227.     snum argMod[32];
  228.     snum argSize[32];
  229.     snum temp1;
  230.     snum temp2;
  231.     char tempc1;
  232.     char tempc2;
  233.  
  234.     
  235.     // function name:
  236.     
  237.     if (*symbol == 0)
  238.         {
  239.             return(0);
  240.         }
  241.     funcNamePtr = symbol;
  242.     funcNameLength = 0;
  243.     
  244.     p = funcNamePtr;
  245.     while ((*p != '_') && (*p != 0))
  246.         {
  247.         funcNameLength++;
  248.         p++;
  249.         }
  250.     
  251.     // if "__" follows the function name, then look for class name or type info
  252.     
  253.     classNameLength = 0;
  254.     typeInfoPtr = NULL;
  255.     
  256.     if ((*p == '_') && (*(p + 1) == '_'))
  257.         {
  258.         
  259.         p += 2; // skip past the "__"
  260.         
  261.         // if the next character is not "F", then get the class name
  262.         
  263.         if (*p != 'F')
  264.             {
  265.             len = 0;
  266.             while ((*p <= '9') && (*p >= '0'))
  267.                 {
  268.                 if (len != 0)
  269.                     len = len * 10;
  270.                 len += *p - '0';
  271.                 p++;
  272.                 }
  273.             classNamePtr = p;
  274.             classNameLength = len;
  275.             p += len;
  276.             }
  277.         
  278.         // if the next character is "F", then get the type info
  279.         
  280.         if (*p == 'F')
  281.             typeInfoPtr = p;
  282.         
  283.         }
  284.  
  285.  
  286. // TEST---
  287.     len = 0;
  288.     copy = stringBuffer;
  289.     if (classNameLength > 0)
  290.         {
  291.         for (i = 0; i < classNameLength; i++)
  292.             *copy++ = *(classNamePtr + i);
  293.         *copy++ = ':';
  294.         *copy++ = ':';
  295.         len += 2 + classNameLength;
  296.         }
  297.     if (funcNameLength > 0)
  298.         {
  299.         for (i = 0; i < funcNameLength; i++)
  300.             *copy++ = *(funcNamePtr + i);
  301.         len += funcNameLength;
  302.         }
  303.  
  304.     if ((typeInfoPtr != NULL) && showTypeInfo)
  305.         {
  306.         argPtr = typeInfoPtr + 1;    // skip the "F"
  307.         
  308.         argCount = 0;
  309.         if (classNameLength > 0)
  310.             {
  311.             argCount = 1;
  312.             argNamePtr[0] = "this";
  313.             argNameLen[0] = 4;
  314.             argMod[0] = 1; // this*=
  315.             }
  316.         argMod[argCount] = 0;
  317.         argNameLen[argCount] = 0;
  318.  
  319.         typeNamePtr = NULL;
  320.         typeNameLen = 0;
  321.         typesize = 0;
  322.         
  323.         while ((*argPtr != 0) && (argCount < 16))
  324.             {
  325.             
  326.             switch (*argPtr)
  327.                 {
  328.               case 'v' :
  329.                   typeNamePtr = "void";
  330.                 typeNameLen = 4;
  331.                 typesize = 0;
  332.                 argPtr++;
  333.                   break;
  334.               case 'c' :
  335.                   typeNamePtr = "char";
  336.                 typeNameLen = 4;
  337.                 typesize = 4;    // 4 bytes on stack ???? ( unless pascal????)
  338.                 argPtr++;
  339.                   break;
  340.               case 's' :
  341.                   typeNamePtr = "short";
  342.                 typeNameLen = 5;
  343.                 typesize = 4;    // seems to be 4 bytes on stack (unless pascal???)
  344.                 argPtr++;
  345.                 break;
  346.               case 'i' :
  347.                   typeNamePtr = "int";
  348.                 typeNameLen = 3;
  349.                 typesize = 4;
  350.                 argPtr++;
  351.                 break;
  352.               case 'l' :
  353.                   typeNamePtr = "long";
  354.                 typeNameLen = 4;
  355.                 typesize = 4;
  356.                 argPtr++;
  357.                 break;
  358.               case 'e' :
  359.                   typeNamePtr = "...";
  360.                 typeNameLen = 3;
  361.                 typesize = 0;
  362.                 argPtr++;
  363.                 break;
  364.               case 'P' :
  365.                 if ((argMod[argCount] & 1) == 0)
  366.                     argMod[argCount] |= 1;    // type*
  367.                 else if ((argMod[argCount] & 2) == 0)
  368.                     argMod[argCount] |= 2;    // type**
  369.                 else
  370.                     argMod[argCount] |= 16; // unknown
  371.                 argPtr++;
  372.                 break;
  373.               case 'U' :
  374.                   argMod[argCount] |= 8;        // unsigned
  375.                 argPtr++;
  376.                 break;
  377.               case 'F' :
  378.                   if (argMod[argCount] & 1)
  379.                     {
  380.                     argMod[argCount] &= 0xfffe; // clear (type*) pointer
  381.                       argMod[argCount] |= 32;        // pointer-to-function
  382.                     }
  383.                 else
  384.                     argMod[argCount] |= 16; // unknown
  385.                 argPtr++;
  386.                 break;
  387.               case '_' :
  388.                   if (argMod[argCount] & 32)        // for pointer-to-function
  389.                     {
  390.                       argMod[argCount] |= 64;     // display of return value not implemented yet
  391.                     typeNamePtr = NULL;
  392.                     }
  393.                 else
  394.                     argMod[argCount] |= 16; // unknown
  395.                 argPtr++;
  396.                 break;
  397.               case '0' :
  398.               case '1' :
  399.               case '2' :
  400.               case '3' :
  401.               case '4' :
  402.               case '5' :
  403.               case '6' :
  404.               case '7' :
  405.               case '8' :
  406.               case '9' :
  407.                   typeNameLen = *argPtr - '0';
  408.                 if ((*(argPtr + 1) >= '0') && (*(argPtr + 1) <= '9'))
  409.                     {
  410.                     argPtr++;
  411.                     typeNameLen = 10 * typeNameLen;
  412.                     typeNameLen += *argPtr - '0';
  413.                     }
  414.                 argPtr++;
  415.                 typeNamePtr = argPtr;
  416.                 argPtr += typeNameLen;
  417.                 typesize = 4;
  418.                 break;
  419.               case 'T' :        // Tx - same as argument x
  420.               case 'N' :
  421.                   if (*argPtr == 'N')
  422.                     {
  423.                     argPtr++;
  424.                     temp1 = *(argPtr + 1) - '0';
  425.                     }
  426.                 else
  427.                     temp1 = 1;
  428.                 argPtr++;
  429.                 
  430.                 for (i = 0; i < temp1; i++)
  431.                     {
  432.                     temp2 = *argPtr - '0';
  433.                     argPtr++;
  434.                     if (classNameLength == 0)
  435.                         temp2--; // arg n is array index n-1 (unless class "this" present)
  436.                     argNamePtr[argCount] = argNamePtr[temp2];
  437.                     argNameLen[argCount] = argNameLen[temp2];
  438.                     argMod[argCount] = argMod[temp2];
  439.                     argSize[argCount] = argSize[temp2];
  440.                     argCount++;
  441.                     argMod[argCount] = 0;
  442.                     }
  443.                 break;
  444.               default:
  445.                   argMod[argCount] |= 16; // unknown
  446.                 argPtr++;
  447.                 break;
  448.                 }
  449.             
  450.             if ((typeNamePtr != NULL) && 
  451.                 (((argMod[argCount] & 32) == 0) || (*argPtr != '_')) )
  452.                 {
  453.                 argNamePtr[argCount] = typeNamePtr;
  454.                 argNameLen[argCount] = typeNameLen;
  455.                 argSize[argCount] = typesize;
  456.                 argCount++;
  457.                 argMod[argCount] = 0;
  458.                 typeNamePtr = NULL;
  459.                 typeNameLen = 0;
  460.                 }
  461.             
  462.             }
  463.         
  464.         *copy++ = '(';
  465.         len++;
  466.         for (i = 0; i < argCount; i++)
  467.             {
  468.             if (argMod[i] & 8)
  469.                 {
  470.                 for (j = 0; j < modUstrlen; j++)
  471.                     *copy++ = *(modUstr + j);
  472.                 *copy++ = ' ';
  473.                 len += (1 + modUstrlen);
  474.                 }
  475.  
  476.             for (j = 0; j < argNameLen[i]; j++)
  477.                 *copy++ = *(argNamePtr[i] + j);
  478.             len += argNameLen[i];
  479.  
  480.             if (argMod[i] & 1)
  481.                 {
  482.                 argSize[i] = 4;
  483.                 *copy++ = '*';
  484.                 len++;
  485.                 }
  486.             if (argMod[i] & 2)
  487.                 {
  488.                 argSize[i] = 4;
  489.                 *copy++ = '*';
  490.                 len++;
  491.                 }
  492.             if (argMod[i] & 16)
  493.                 {
  494.                 *copy++ = '?';
  495.                 len++;
  496.                 }
  497.             if (argMod[i] & 32)
  498.                 {
  499.                 *copy++ = ' ';
  500.                 *copy++ = '(';
  501.                 *copy++ = '*';
  502.                 *copy++ = ' ';
  503.                 *copy++ = '?';
  504.                 *copy++ = ')';
  505.                 *copy++ = '(';
  506.                 *copy++ = ')';
  507.                 len += 8;
  508.                 }
  509.             if ((stackdataPtr != NULL) && (argSize[i] > 0))
  510.                 {
  511.                 *copy++ = '=';
  512.                 len++;
  513.                 for (j = 0; j < argSize[i]; j++)
  514.                     {
  515.                     tempc1 = (*stackdataPtr & 0xf0) >> 4;
  516.                     tempc2 = *stackdataPtr & 0x0f;
  517.                     if (tempc1 < 10)
  518.                         *copy++ = '0' + tempc1;
  519.                     else
  520.                         *copy++ = 'A' + (tempc1 - 10);
  521.                     if (tempc2 < 10)
  522.                         *copy++ = '0' + tempc2;
  523.                     else
  524.                         *copy++ = 'A' + (tempc2 - 10);
  525.                     len += 2;
  526.                     stackdataPtr++;
  527.                     }
  528.                 }
  529.             if (i < (argCount - 1))
  530.                 {
  531.                 *copy++ = ',';
  532.                 *copy++ = ' ';
  533.                 len += 2;
  534.                 }
  535.             }
  536.         *copy++ = ')';
  537.         len++;
  538.             
  539.         }
  540.         
  541.     *copy = 0;    // null terminated string
  542.     
  543.         
  544.     
  545.     return(len);
  546.     
  547. }
  548.         
  549.  
  550. DumpBytes(Ptr p, short s)
  551.     {
  552.     int i;
  553.     Ptr addr;
  554.     
  555.     addr = p;
  556.     for (i = 0; i < s; i++)
  557.         {
  558.         if (i % 32 == 0)
  559.             printf("%08x: ", p - addr);
  560.         
  561.         printf("%02x", *p++ & 0x0ff);
  562.         
  563.         if (i % 4 == 3)
  564.             printf(" ");
  565.         
  566.         if (i % 32 == 31)
  567.             printf("\n");
  568.         }
  569.     if (i % 32 != 0)
  570.         printf("\n");
  571.     }
  572.  
  573. #ifndef THINK_C
  574. void ParseArgs(int argc, char **argv)
  575.     {
  576.     char type;
  577.     char *arg;
  578.     /*------- Get command line arguments ----------------*/
  579.         
  580.     type = ' ';
  581.     for (argv++, argc--; argc--; argv++)    /* skip av[0] */
  582.         {
  583.         arg = (char *) *argv;
  584.         
  585.         type = (arg[0] == '-') ? (char) arg[1] : type;
  586.         if (arg[0] == '-')
  587.             arg += 2;
  588.  
  589.         switch (type)
  590.  
  591.             {
  592.             case 'f' :            /* set the tracefile name */
  593.                 if  (*arg == 0)
  594.                     break;
  595.                 (void) strcpy(gFileName, arg);
  596.                 c2pstr(gFileName);
  597.                 break;        
  598.  
  599.             case ' ':
  600.                 break;
  601.             case 'q' : gVerboseMode = false;
  602.                 break;
  603.             default:
  604.                 (void) printf("DumpTracks: illegal option [%c]\n", (char) type);
  605.                 (void) printf("format DumpTracks [ -f tracefilename] [-q] \n");
  606.                 exit(3);
  607.  
  608.             }
  609.         }
  610.  
  611.     return;
  612.     
  613.     }
  614. #endif
  615.  
  616. // Prints StackPeek data
  617. void PrintFmt01(char *fmt01Ptr)
  618. {
  619. char *stackdata;
  620. char *modulesym;
  621. char *callersym;
  622. snum modulelen;
  623. snum callerlen;
  624. char symbolName[256];
  625. char module[256], caller[256];
  626.  
  627.  
  628.     stackdata = fmt01Ptr;
  629.     modulesym = SkipPStr(stackdata);
  630.     callersym = SkipPStr(modulesym);
  631.     
  632.     CopyPStr(modulesym, module);
  633.     CopyPStr(callersym, caller);
  634.     
  635.     p2cstr(module);
  636.     p2cstr(caller);
  637.     
  638.     modulelen = *modulesym;
  639.     callerlen = *callersym;
  640.     
  641.     // if (0 ) printf("Decoding '%s' and '%s', %d, %d\n", module, caller, strlen(module), strlen(caller));
  642.     
  643.     (void) DecodeSym(symbolName, module, true, (Ptr) stackdata + 8);
  644.  
  645.     printf("'%s'\n", symbolName);
  646.  
  647.     (void) DecodeSym(symbolName, caller, true, (Ptr) stackdata + 8);
  648.     
  649.     printf("    called by '%s'\n", symbolName);
  650.  
  651.     return;
  652. }
  653.     
  654.  
  655.  
  656. void PrintFmt02(Ptr dataPtr, short dataLength)
  657. {
  658. int i;
  659. unsigned char ascii[18];
  660. unsigned char ebcdic[18];
  661. unsigned char c;
  662. BytePtr p;
  663. int pos;
  664. int linelen;
  665. int prtlen;
  666.     
  667.  
  668.     // Get length from LL field (length of print data does not include 2 bytes of LL)
  669.     
  670.     prtlen = dataLength;
  671.     
  672.     p = (BytePtr)dataPtr;
  673.     pos = 0;
  674.     
  675.     /* Here is a sample output line to line up the header text: */
  676.     /******"(00:  0000 0000 0D4C 4F4B  4920 5761 7220 524F    ……………LOKI War RO    IIIII<!.®ÄØ/ºÄ™!  ****/
  677.     printf("\n");    
  678.  
  679. #ifdef PRINTEBCIDIC
  680.     printf("                                                 ---- ASCII -----    ---- EBCDIC ----\n");
  681. #else
  682.     printf("                                                 ---- ASCII -----\n");
  683. #endif        
  684.  
  685.     while (prtlen > 0)
  686.         {
  687.  
  688.         printf("%02X:  ", (pos & 0x0ff));
  689.  
  690.         linelen = 16;
  691.         if (linelen > prtlen)
  692.             linelen = prtlen;
  693.  
  694.         for (i = 0; i < linelen; i++)
  695.         {
  696.             c = *p++;
  697.             pos++;
  698.             if ((c < 0x20) || (c == 0x7f))    // normally nonprinting characters
  699.                 ascii[i] = '.';    
  700.             else
  701.                 ascii[i] = c;
  702.                 
  703.             printf("%02X", c);
  704.             
  705.             if ((i == 7) || (i == 15))
  706.                 printf("  ");
  707.             else if ((i% 2) == 1)
  708.                 printf(" ");
  709.  
  710.         }
  711.         for (i = linelen; i < 16; i++)
  712.         {
  713.             printf("  ");
  714.             if ((i == 7) || (i == 15))
  715.                 printf("  ");
  716.             else if ((i% 2) == 1)
  717.                 printf(" ");
  718.         }            
  719.  
  720.         CopyEbcdicToAscii(ascii, ebcdic, linelen);
  721.         ascii[linelen] = ' ';
  722.         ebcdic[linelen] = ' ';
  723.         for (i = (linelen + 1); i < 17; i++)
  724.             {
  725.             ascii[i] = ' ';
  726.             ebcdic[i] = ' ';
  727.             }
  728.         ascii[17] = 0;
  729.         ebcdic[17] = 0;
  730. #ifdef PRINTEBCIDIC
  731.         printf("  %s   %s\n", ascii, ebcdic);
  732. #else
  733.         printf("  %s\n", ascii);
  734. #endif        
  735.         prtlen -= linelen;
  736.         
  737.         }
  738.  
  739. return;
  740.     
  741. }
  742.     
  743.  
  744. void PrintFmt04(long dataLong)
  745. {
  746. char     data1, data2, data3, data4;
  747.     data1 = (dataLong >> 24) & 0x0ff;
  748.     if ((data1 < 0x20) || (data1 == 0x7f))    // normally nonprinting characters
  749.         data1 = '.';    
  750.     data2 = (dataLong >> 16) & 0x0ff;
  751.     if ((data2 < 0x20) || (data2 == 0x7f))    // normally nonprinting characters
  752.         data2 = '.';    
  753.     data3 = (dataLong >> 8) & 0x0ff;
  754.     if ((data3 < 0x20) || (data3 == 0x7f))    // normally nonprinting characters
  755.         data3 = '.';    
  756.     data4 = dataLong & 0x0ff;
  757.     if ((data4 < 0x20) || (data4 == 0x7f))    // normally nonprinting characters
  758.         data4 = '.';    
  759.     printf("DATA = 0x%08X   #%d    '%c%c%c%c'\n", 
  760.      dataLong, dataLong, data1, data2, data3, data4);
  761. }
  762.  
  763. // Format of data is:
  764. // Length long word + Data [length bytes]
  765. void PrintFmt05(BytePtr data)
  766. {
  767. long *dataLong;
  768.  
  769.     dataLong = (long *)data;
  770.     data += 4;    // skip past the long
  771.     p2cstr(data);
  772.     printf("'%s'  %-5ld         0x%-8lX\n",
  773.         data, *dataLong, *dataLong);
  774.     c2pstr(data);
  775.     // PrintFmt04(*dataLong);
  776. }
  777.  
  778. //    Format of dataPtr is
  779. //        Length long [], Data [length bytes], PStr [Type Name]
  780.  
  781. void PrintFmt06(BytePtr data)
  782. {
  783. BytePtr typeStr, result;
  784. long *length;
  785. long    extraData;
  786.  
  787.     length = (long *)data;
  788.     data += 4;    // skip past the long
  789.     typeStr = data + *length;
  790.  
  791.     result = PrettyDump(data, typeStr);
  792.     extraData = (long)result - (long)typeStr;
  793.  
  794.  
  795.     if (result == nil)
  796.         {
  797.             // printf("Data Type Not Found.  Printing as data\n");
  798.             PrintFmt02(data, *length);
  799.         }
  800.     else
  801.     if (extraData < 0)
  802.     {
  803.         printf("••• Not enough data sent.  Some data is invalid •••\n");
  804.     }
  805.     
  806.     else
  807.     if (result-typeStr > 0)
  808.         {
  809.             printf("Dumping extra data...\n");
  810.             PrintFmt02(result, extraData);
  811.         }
  812.     // Check here later for extra data appended...  (that didn't fit in the record)
  813. }
  814.  
  815.  
  816. void PrintRecord(snum length)
  817.     {
  818. register NewRecordTemplate    *template;
  819. long dataLong;
  820. Str255    maskName;
  821. BytePtr dataStart;
  822.  
  823.     if (length >= 4)
  824.         {
  825.         template = (NewRecordTemplate *)gReadBuff;        
  826. #ifdef    TEST
  827.         printf("template->length %d\n", template->length);
  828.         printf("template->diagID %d\n", (short) template->diagID);
  829.         printf("template->partCode %d\n", (short) template->partCode);
  830.         printf("template->formatID %d\n", (short) template->formatID);
  831. //        printf("template->timestamp %ld\n", template->timeStamp );        
  832. #endif
  833.  
  834.         GetIndString(maskName, kMaskStringListID, (template->diagID & 0x7F) + 1);// Get String list name.
  835.         //  +1 because mask numbers start at 0, str#'s start at 1
  836.         
  837.         //
  838.         // Either DiagID is out of range or it is a new trace DiagID that has 
  839.         // not been added to the STR# resource in cdev.r
  840.         //
  841.         if (maskName[0] == 0)        // Perhaps out of range or STR# list not there...
  842.             strcpy((char *)maskName,(char *)"\p ???");
  843.  
  844.         if (template->partCode == 0)    
  845.         {
  846.             lastDiagID = template->diagID;    
  847.             p2cstr(maskName);
  848.             if (gVerboseMode)    printf("\n++ Trace Record ");
  849.             if (!gVerboseMode) printf("\n\n");
  850.             if (gVerboseMode)    PrintTimeAndDate(template->timeStamp);
  851.             if (gVerboseMode)    printf(" ++\n++ DiagID %02d ( %s ) ++\n", template->diagID, maskName);
  852.             if (0) printf("Format ID = %d\n", (short) template->formatID);
  853.         }
  854.         else
  855.             if (template->diagID != lastDiagID)    // First partCode must be zero
  856.                 printf(" ••• Trace partCode 0 expected •••\n");
  857.  
  858.         if (gVerboseMode)    printf("(%3d-%2d) ",(short) template->diagID & 0x7f,(short)template->partCode & 0x7f);
  859.  
  860.         dataStart = (BytePtr)template;
  861.         dataStart += sizeof(template);
  862.  
  863.         dataStart  = &template->formatID;
  864.         dataStart++;
  865.                 
  866.         switch (template->formatID)
  867.             {
  868.           case 0x00:
  869.                 printf("••• Data Lost Record •••\n");
  870.             break;
  871.           case 0x01:
  872.               if (gVerboseMode)    printf("STACKPEEK\n");
  873.             PrintFmt01(dataStart);
  874.             break;
  875.             
  876.           case 0x02:
  877.             if (gVerboseMode)    printf("DATA  ");        
  878.             // Length of Template ---  sizeof(template) -2 -- was 12 prior..
  879.               PrintFmt02(dataStart, template->length - 10); // 10  = Length of template!
  880.             break;
  881.          
  882.           case 0x03:
  883.               {
  884.             char *bytePtr;
  885.                 bytePtr = dataStart;
  886.                 // bytePtr++;
  887.                 if (gVerboseMode)    printf("PSTR \n");
  888.             
  889.               p2cstr(bytePtr);
  890.             printf("\"%s\"\n", bytePtr);
  891.             c2pstr(bytePtr);
  892.             }
  893.             break;
  894.         
  895.            case 0x04:
  896.             if (gVerboseMode)    printf("LONG \n");
  897.             dataLong = *(long *)dataStart;
  898.             PrintFmt04(dataLong);
  899.             break;
  900.         
  901.           case 0x05: 
  902.             if (gVerboseMode)    printf("PSTR + LONG \n");
  903.               PrintFmt05(dataStart);
  904.             break;
  905.         
  906.           case 0x06:
  907.               if (gVerboseMode) printf("FORMATTED TYPE DUMP\n");
  908.             PrintFmt06(dataStart);
  909.             break;
  910.             
  911.           default:
  912.               printf("•••• Unknown FormatID %d ••••\n", (short)template->formatID);        
  913.             break;
  914.             }
  915.         
  916.         // printf("\n");        // Space in between part codes....
  917.         }
  918.  
  919.     return;
  920.     
  921.     }
  922.  
  923. void PrintTimeAndDate(long    timestamp)
  924. {
  925. Str31    dateStr,timeStr;
  926.     IUDateString(timestamp, abbrevDate, dateStr);
  927.     p2cstr(dateStr);
  928.     IUTimeString(timestamp, true, timeStr);
  929.     p2cstr(timeStr);
  930.     printf("%s at %s",timeStr,dateStr);
  931. }
  932.  
  933.  
  934. snum ReadFileRecords(short refNum)
  935. {
  936. snum result;
  937. shex recordSize;    // Size of the current trace record being read
  938. long readAmount;    // Number of bytes to read from file
  939. long lostAmount;    // Number of bytes of record that will not fit in buffer
  940. Boolean gotLength;    // true if we read the length field
  941.     
  942.     // While no errors, retrieve trace records...
  943.     
  944.     result = 0;
  945.     
  946.     while (result == noErr)
  947.         {
  948.         
  949.         // Read in the record length field (2 bytes):
  950.         
  951.         gotLength = false;
  952.         
  953.         readAmount = 2;
  954.         result = FSRead(refNum, &readAmount, (Ptr) gReadBuff);
  955.         
  956.         if ((result == noErr) && (readAmount != 2))
  957.             result = paramErr; // use this error to flag this unexpected condition
  958.         else
  959.             {
  960.             gotLength = true;
  961.             
  962.             // Read in the remainder of this record:
  963.             // (Do not read in more than the buffer will hold)
  964.             
  965.             recordSize = *((shex *) gReadBuff);
  966.             readAmount = recordSize - 2;
  967.             
  968.             if (readAmount > gReadBuffSize)
  969.                 {
  970.                 lostAmount = readAmount - gReadBuffSize;
  971.                 readAmount = gReadBuffSize;
  972.                 }
  973.             else
  974.                 lostAmount = 0;
  975.  
  976.             result = FSRead(refNum, &readAmount, ((Ptr) gReadBuff) + 2);
  977.  
  978.             // If the trace record was too big for the buffer, move file mark past
  979.             // the end of this record so the next read will get th next record...
  980.             
  981.             if ((result == noErr) && (lostAmount != 0))
  982.                 result = SetFPos(refNum, fsFromMark, lostAmount);
  983.             
  984.             // Print this record:
  985.             
  986.             if (result == noErr)
  987.                 PrintRecord(readAmount + 2);
  988.             
  989.             }
  990.         }
  991.     
  992.     // If the error was end-of-file reached while reading length, then return noErr
  993.     
  994.     if ((result == eofErr) && ! gotLength)
  995.         result == noErr;
  996.     
  997.     return(result);
  998.     
  999.     }
  1000.  
  1001. Str31    gKnownTypeList[] = {"\pByte", "\pWord", "\pLong", "\pSignedByte", "\pSignedWord", "\pSignedLong", 
  1002. "\pUnsignedByte", "\pUnsignedWord", "\pUnsignedLong", "\pBoolean", "\ppString", "\pcString", 
  1003. "\pText", "\pSkip", "\pAlign", "\pHandle", "\pPointer"};    
  1004.  
  1005. enum {kByte, kWord, kLong, kSignedByte, kSignedWord, kSignedLong, kUnsignedByte, kUnsignedWord, kUnsignedLong, kBoolean, kpString,
  1006. kcString, kText, kSkip, kAlign, kHandle, kPointer, kNumTypes};
  1007.  
  1008.  
  1009.  
  1010. BytePtr    gDataPtr;
  1011. short gNumResources;
  1012. TmplHandle    gDataHandle[10];
  1013.  
  1014.  
  1015. BytePtr SkipPStr(BytePtr str)
  1016. {
  1017. short num, x;
  1018.     num = (short) *str;
  1019.     str++;
  1020.     for (x=0;x<num;x++)
  1021.         str++;
  1022.     return (str);
  1023. }
  1024.  
  1025.  
  1026. // Note:  gKnownTypeList is defined above, and contains a list of the basic
  1027. // type definitions, such as Long, Boolean, etc...
  1028. BytePtr    DumpMemory (BytePtr wh, char *type)
  1029. {
  1030. short x;
  1031. long    *lp;
  1032. short    *sp;
  1033.     lp = (long *)wh;
  1034.     sp = (short *)wh;
  1035.     
  1036.     if (wh == nil) {printf("DumpMemory err:  data ptr = nil\n");return nil;}
  1037.     
  1038.     x = -1;
  1039.     
  1040.     if (type[1] == '^') x = kPointer;
  1041.     if (type[2] == '^') x = kHandle;
  1042.     
  1043.     if (x == -1)    // if not a pointer (^xxx) or handle (^^dataBlock)
  1044.     {
  1045.         for (x=0;x<kNumTypes;x++)
  1046.             if (strcmp(type, (char *)gKnownTypeList[x]) == 0) break;
  1047.     } 
  1048.     
  1049.     switch (x)
  1050.     {
  1051.         case kByte:     
  1052.         case kSignedByte:     
  1053.             printf("%-02d  ", *wh);wh+=1;break;
  1054.         case kWord: 
  1055.         case kSignedWord: 
  1056.             printf("%-6d ", *sp);wh+=2;break;
  1057.         case kSignedLong:     
  1058.         case kLong:     
  1059.             printf("%-08ld ", *lp);wh+=4;break;        
  1060.         case kUnsignedByte:     
  1061.             printf("0x%-02X  = '%c'", *wh, *wh);wh+=1;break;        
  1062.         case kUnsignedWord: 
  1063.             printf("0x%-6X ", *sp);wh+=2;break;
  1064.         case kUnsignedLong:     
  1065.             printf("0x%-08ld ", *lp);wh+=4;break;
  1066.         case kBoolean:     
  1067.             if (*wh)
  1068.                 printf("true ");
  1069.             else
  1070.                 printf("false ");
  1071.             wh+=1;break;        // Check this...
  1072.  
  1073.         case kpString:     
  1074.             {
  1075.                 short len = *wh,c;
  1076.                 
  1077.                 wh++;
  1078.                 printf("pString = '");
  1079.                 for (c=0;c<len;c++)
  1080.                     printf("%c", *wh++);
  1081.                 printf("'");
  1082.                 break;
  1083.             }
  1084.         case kcString:     
  1085.             {
  1086.                 printf("cString = '");
  1087.                 while (*wh)
  1088.                     printf("%c", *wh++);
  1089.                 printf("'");
  1090.                 break;
  1091.             }
  1092.     
  1093.         case kText:  break;        // Not supported... 
  1094.         
  1095.         case kSkip:
  1096.             printf("0x%-4X", *sp);
  1097.             wh+=2;
  1098.             break;
  1099.  
  1100.         case kAlign: 
  1101.         printf("ALIGN byte (%d)", *wh);
  1102.         wh++;break;
  1103.  
  1104.         case kHandle:     
  1105.             printf("0x%-08lX ", *lp);wh+=4;break;
  1106.             
  1107.         case kPointer:     
  1108.             printf("0x%-08lX ", *lp);wh+=4;break;
  1109.  
  1110.         case kNumTypes:     // Specified template was not of standard type....
  1111.             if (0)
  1112.             {
  1113.                 p2cstr(type);
  1114.                 printf("Looking for type '%s'\n", type);
  1115.                 c2pstr(type);
  1116.             }
  1117.             wh = DMWithTemplate(wh, type);
  1118.             break;    
  1119.         default :
  1120.             p2cstr(type);
  1121.             printf("DT Err: Unknown type: '%s'\n", type);
  1122.             c2pstr(type);
  1123.             break;
  1124.     };
  1125.     return wh;
  1126. }
  1127.  
  1128.  
  1129. // Displays info on template, and points to the next one
  1130. BytePtr HandleField(BytePtr field, Boolean printOn)
  1131. {
  1132. short *count, r;
  1133. char *fieldName, *type;
  1134.  
  1135.     if (printOn) printf("    '");
  1136.     fieldName = field;
  1137.     if (printOn)    PrintPStr(fieldName);
  1138.     field = SkipPStr(field);
  1139.     if (printOn) printf("'    ");
  1140.     
  1141.     type = field;
  1142.     field = SkipPStr(field);
  1143.     
  1144.     // if (printOn) (void) PrintPStr(type);
  1145.     // if (printOn) printf ("  ");
  1146.     count = (short *) field;
  1147.     
  1148.     
  1149.     field += 2;
  1150.     
  1151.     if (printOn) 
  1152.     for (r = 0; r < *count; r++)    
  1153.         {
  1154.             if (gDataPtr == nil) printf("Type dump err..\n");    // doesnt happen 
  1155.             gDataPtr = DumpMemory(gDataPtr, type);    // Call recursivly
  1156.             if (gDataPtr == nil) {printf("DumpMemory Error\n");break;}
  1157.         }
  1158.     if (printOn) printf("\n");    
  1159.     return field;
  1160. }
  1161.  
  1162. // Displays info on template, and points to the next one
  1163. BytePtr HandleTemplate(BytePtr    tmpl, Boolean printOn)
  1164. {
  1165. short     x, *fields;
  1166. char *templateName;
  1167.  
  1168.     templateName = tmpl;
  1169.     tmpl = (char *) SkipPStr(tmpl);
  1170.  
  1171.     if (printOn) 
  1172.     {
  1173.         (void) PrintPStr(templateName);        // Special Type Name
  1174.         printf("\n");
  1175.     }
  1176.     fields = (short*) tmpl;
  1177.     tmpl += 2;
  1178.  
  1179.     // I assume there will be no data structrures with more than 100 fields...
  1180.     if (*fields > 100) {printf("Type Dump Error.  %d is too many fields (>100) \n", *fields);return nil;}
  1181.     
  1182.     for (x=0;x < *fields;x++)
  1183.         tmpl = HandleField(tmpl, printOn);
  1184.     return tmpl;    // this now points to the next template...
  1185. }
  1186.  
  1187.  
  1188. short TypeDumpSetUp(short SysFolderRefNum)
  1189. {
  1190. short x;
  1191. short err;
  1192. short prefsResRefNum;
  1193.  
  1194.     prefsResRefNum = OpenRFPerm("\pDebugger Prefs", SysFolderRefNum, fsRdWrPerm);
  1195.     err = ResError();
  1196.     if (err != noErr) prefsResRefNum = 0;
  1197.     gNumResources = CountResources('mxwt');
  1198.     if (gNumResources >10) gNumResources = 10;    /* Heaven forbid they have more... */
  1199.     
  1200.     if (gNumResources > 0)
  1201.     for (x=0;x<gNumResources;x++)
  1202.     {
  1203.         gDataHandle[x] = (TmplHandle)GetIndResource('mxwt', x+1);
  1204.         
  1205.         // if (gDataHandle) printf("Loaded mxwt resource\n");
  1206.         
  1207.         if (gDataHandle[x] == nil) {printf("Failed to load resource\n");gNumResources = x-1;return false;}
  1208.         DetachResource((Handle)gDataHandle[x]);
  1209.         HLock((Handle)gDataHandle[x]);
  1210.     }
  1211.     if (prefsResRefNum)
  1212.         CloseResFile(prefsResRefNum);        
  1213.     return x;
  1214. }
  1215.  
  1216. void TypeDumpCloseDown()
  1217. {
  1218. short x;
  1219.     for (x=0;x<gNumResources;x++)
  1220.     {
  1221.         HUnlock((Handle)gDataHandle[x]);
  1222.         DisposHandle((Handle)gDataHandle[x]);
  1223.         gDataHandle[x] = nil;
  1224.     }
  1225. }
  1226.  
  1227. ComparePStr(char *a, char *b)
  1228. {
  1229. char len, x;
  1230.     len = *a;
  1231.     for (x=0;x<=len;x++)
  1232.         if (*a++ != *b++) return false;
  1233.     return true;
  1234. }
  1235.  
  1236.  
  1237. BytePtr DMWithTemplate (BytePtr wh, char *searchType)
  1238. {
  1239. short     numTemplates;
  1240. short     x, t;
  1241. BytePtr        tmpl;
  1242. Boolean PrintRecord;
  1243.  
  1244.     gDataPtr = wh;
  1245.     for (t=0;t<gNumResources;t++)
  1246.     {
  1247.         numTemplates = (**gDataHandle[t]).NumTemplates;
  1248.         tmpl = (BytePtr) &(**gDataHandle[t]).FirstTemplate;
  1249.         
  1250.         for (x=0;x < numTemplates;x++)        // numTemplates
  1251.             {
  1252.                 PrintRecord = ComparePStr(searchType, tmpl);        /* Is this it?  If so, print it out.. */
  1253.                 tmpl = HandleTemplate(tmpl, PrintRecord);
  1254.                 if (PrintRecord) return gDataPtr;
  1255.             }
  1256.     }
  1257.     return nil;
  1258. }
  1259.  
  1260. BytePtr PrintPStr(BytePtr str)
  1261. {
  1262. register short num, x, i;
  1263.     num = (short) *str;
  1264.     str++;
  1265.     for (x=0;x<num;x++)
  1266.         printf("%c", *str++);
  1267.     for (i=x;i< 17;i++)
  1268.         printf(" ");
  1269.     return (str);
  1270. }
  1271.  
  1272. BytePtr PrettyDump(BytePtr    data, BytePtr typeString)
  1273. {
  1274. BytePtr    found;
  1275.     found = DumpMemory((BytePtr)data, typeString);
  1276.     if (found == nil) 
  1277.         {
  1278.             p2cstr(typeString);
  1279.             printf("'%s' Unknown Data Type.", typeString);
  1280.             c2pstr(typeString);
  1281.         }
  1282.     printf("\n");
  1283.     return found;
  1284. }
  1285.  
  1286.